home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.1 (Developer) [x86] / NeXT Step 3.1 Intel dev.cdr.dmg / NextDeveloper / Examples / AppKit / ScrollDoodScroll / Controller.m < prev    next >
Text File  |  1992-05-28  |  8KB  |  284 lines

  1. // Controller.m
  2. // By Jayson Adams, NeXT Developer Support Team
  3. // You may freely copy, distribute and reuse the code in this example.
  4. // NeXT disclaims any warranty of any kind, expressed or implied, as to its
  5. // fitness for any particular use.
  6.  
  7. #import <appkit/appkit.h>
  8. #import <objc/NXStringTable.h>
  9.  
  10. #import "Controller.h"
  11. #import "CustomCell.h"
  12. #import "NiftyMatrix.h"
  13. #import "PostScriptView.h"
  14.  
  15. @implementation Controller:Object
  16.  
  17.  
  18. /* delegation methods */
  19.  
  20. - appDidInit:sender
  21. {
  22.   /* create a matrix and stick it in the scroll view */
  23.     [self createScrollingMatrix];
  24.     
  25.   /* bring the window on screen */
  26.     [[scrollView window] makeKeyAndOrderFront:NULL];
  27.  
  28.     [self setupTileView];
  29.     [[tileScrollView window] orderFront:NULL];
  30.     
  31.     return self;
  32. }
  33.  
  34. /* instance methods */
  35.  
  36. - createScrollingMatrix
  37. {
  38.     NXRect    scrollRect, matrixRect;
  39.     NXSize    interCellSpacing = {0.0, 0.0}, cellSize;
  40.     
  41.   /* set the scrollView's attributes */
  42.     [scrollView setBorderType:NX_BEZEL];
  43.     [scrollView setVertScrollerRequired:YES];
  44.     [scrollView setHorizScrollerRequired:NO];
  45.         
  46.   /* get the scrollView's dimensions */
  47.     [scrollView getFrame:&scrollRect];
  48.  
  49.   /* determine the matrix bounds */
  50.     [ScrollView getContentSize:&(matrixRect.size)
  51.             forFrameSize:&(scrollRect.size)
  52.         horizScroller:YES
  53.         vertScroller:YES
  54.         borderType:NX_BEZEL];
  55.     
  56.   /* prepare a matrix to go inside our scrollView */
  57.     matrix = [[NiftyMatrix alloc] initFrame:&matrixRect 
  58.                   mode:NX_LISTMODE
  59.                   cellClass:[CustomCell class]
  60.                   numRows:0
  61.                   numCols:1];
  62.     
  63.   /* we don't want any space between the matrix's cells  */
  64.     [matrix setIntercell:&interCellSpacing];
  65.       
  66.   /* fill the matrix with some cells */
  67.     [self fillMatrix];
  68.     
  69.   /* resize the matrix's cells and size the matrix to contain them */
  70.     [matrix getCellSize:&cellSize];
  71.     cellSize.width = NX_WIDTH(&matrixRect);
  72.     [matrix setCellSize:&cellSize];
  73.     [matrix sizeToCells];
  74.     [matrix setAutosizeCells:YES];
  75.     
  76.   /*
  77.    * when the user clicks in the matrix and then drags the mouse out of
  78.    * scrollView's contentView, we want the matrix to scroll
  79.    */
  80.     [matrix setAutoscroll:YES];
  81.     
  82.   /* stick the matrix in our scrollView */
  83.     [scrollView setDocView:matrix];
  84.     
  85.   /* set things up so that the matrix will resize properly */
  86.     [[matrix superview] setAutoresizeSubviews:YES];
  87.     [matrix setAutosizing:NX_WIDTHSIZABLE];
  88.     
  89.   /* set the matrix's single- and double-click actions */
  90.     [matrix setTarget:self];
  91.     [matrix setAction:@selector(singleClick:)];
  92.     [matrix setDoubleAction:@selector(doubleClick:)];
  93.     
  94.   /* select a cell, for starters */
  95.     [[matrix selectCellAt:0 :0] sendAction];
  96.     
  97.     return self;
  98. }
  99.  
  100. - fillMatrix
  101. {
  102.     BOOL    done = NO;
  103.     char    buffer[10];
  104.     int        i = 0;
  105.     const char    *string;
  106.     id        newCell;
  107.     
  108.   /* create a cell for each string */
  109.     while (!done) {
  110.     sprintf(buffer, "%d", i);
  111.     if (string = [stringTable valueForStringKey:buffer]) {
  112.           /* create a new cell if there's a string */
  113.         [matrix addRow];
  114.         newCell = [matrix cellAt:i :0];
  115.         [newCell setTag:(i * 16)];
  116.         [newCell setStringValueNoCopy:string];
  117.     } else {
  118.         done = YES;
  119.     }
  120.     i++;
  121.     }
  122.     
  123.   return self;
  124. }
  125.  
  126. - setupTileView
  127. {
  128.     const NXRect    *paperRect;
  129.     NXCoord        leftMargin, rightMargin, topMargin, bottomMargin;
  130.     NXRect        psViewRect;
  131.  
  132.     [tileScrollView setVertScrollerRequired:YES];
  133.     [tileScrollView setHorizScrollerRequired:YES];
  134.     [tileScrollView setBorderType:NX_NOBORDER];
  135.  
  136.   /* get the paper's bounds (8.5 x 11) and margins */
  137.     paperRect = [[NXApp printInfo] paperRect];
  138.     [[NXApp printInfo] getMarginLeft:&leftMargin
  139.                    right:&rightMargin
  140.                top:&topMargin
  141.                bottom:&bottomMargin];
  142.     
  143.   /* the docView should fit within the margins */      
  144.     psViewRect = *paperRect;
  145.     psViewRect.size.width -= (leftMargin + rightMargin);
  146.     psViewRect.size.height -= (topMargin + bottomMargin);
  147.     
  148.   /* create the docView and place it within its scrollView */
  149.     psView = [[PostScriptView alloc] initFrame:&psViewRect];
  150.     [tileScrollView setDocView:psView];
  151.  
  152.     return self;
  153. }
  154.  
  155. - nextItem:sender
  156. {
  157.     int        nextRow;
  158.     
  159.   /* don't move to the "next" cell if multiple cells selected */
  160.     if ([self multipleCellsSelected]) {
  161.     NXRunAlertPanel(NULL,
  162.             [stringTable valueForStringKey:"mulCellsSelected"],
  163.             [stringTable valueForStringKey:"oops"], NULL, NULL);
  164.     return self;
  165.     }
  166.     
  167.   /* can't select the next cell if there isn't a currently-selected cell */
  168.     if (![matrix selectedCell]) {
  169.     NXRunAlertPanel(NULL,
  170.             [stringTable valueForStringKey:"noCurrentCell"],
  171.             [stringTable valueForStringKey:"yikes"], NULL, NULL);
  172.     return self;
  173.     }
  174.     
  175.   /* select the next cell, if it exists */
  176.     nextRow = [matrix selectedRow] + 1;
  177.     if (nextRow != [matrix cellCount]) {
  178.     [matrix selectCellAt:nextRow :0];
  179.       
  180.       /* make sure it's visible */
  181.     [matrix scrollCellToVisible:nextRow :0];
  182.       
  183.       /* behave as if the user clicked on the newly-selected cell */
  184.     [matrix sendAction];
  185.     } else {
  186.     NXRunAlertPanel(NULL,
  187.             [stringTable valueForStringKey:"nextCellNonexistant"],
  188.             [stringTable valueForStringKey:"bummer"], NULL, NULL);
  189.     }
  190.     
  191.     return self;
  192. }
  193.  
  194. - previousItem:sender
  195. {
  196.     int        previousRow;
  197.     
  198.   /* don't move to the "previous" cell if multiple cells selected */
  199.     if ([self multipleCellsSelected]) {
  200.     NXRunAlertPanel(NULL,
  201.             [stringTable valueForStringKey:"mulCellsSelected"],
  202.             [stringTable valueForStringKey:"oops"], NULL, NULL);
  203.     return self;
  204.     }
  205.     
  206.   /* can't select previous cell if there no currently-selected cell */
  207.     if (![matrix selectedCell]) {
  208.     NXRunAlertPanel(NULL,
  209.             [stringTable valueForStringKey:"noCurrentCell"],
  210.             [stringTable valueForStringKey:"yikes"], NULL, NULL);
  211.     return self;
  212.     }
  213.     
  214.   /* select the previous cell, if it exists */
  215.     previousRow = [matrix selectedRow] - 1;
  216.     if (previousRow != -1) {
  217.     [matrix selectCellAt:previousRow :0];
  218.       
  219.       /* make sure the newly-selected cell's visible */
  220.     [matrix scrollCellToVisible:previousRow :0];
  221.       
  222.       /* behave as if the user clicked on the newly-selected cell */
  223.     [matrix sendAction];
  224.     } else {
  225.     NXRunAlertPanel(NULL,
  226.             [stringTable valueForStringKey:"prevCellNonexistant"],
  227.             [stringTable valueForStringKey:"bummer"], NULL, NULL);
  228.     }
  229.     
  230.     return self;
  231. }
  232.  
  233. - (BOOL)multipleCellsSelected
  234. {
  235.   /* reset the counter */
  236.     selectedCount = 0;
  237.     
  238.   /* get each selected cell to send the incrementCount method to us */
  239.     [matrix sendAction:@selector(incrementCount:) to:self forAllCells:NO];
  240.     
  241.   /* if more than one, return true */
  242.     return (selectedCount > 1);
  243. }
  244.  
  245. - (BOOL)incrementCount:sender
  246. {
  247.   /*
  248.    * once the counter reaches two, we know that more than one cell's
  249.    * selected;  if that's the case, return NO so that the matrix will
  250.    * discontinue having selected cells send incrementCount: to us
  251.    */
  252.     
  253.     return (++selectedCount < 2);
  254. }
  255.  
  256. - singleClick:sender
  257. {
  258.     if ([self multipleCellsSelected]) {
  259.     [textField setStringValueNoCopy:""];
  260.     } else {
  261.     [textField setStringValueNoCopy:[[matrix selectedCell] stringValue]];
  262.     }
  263.     return self;
  264. }
  265.  
  266. - doubleClick:sender
  267. {
  268.     NXRunAlertPanel(NULL, [stringTable valueForStringKey:"doubleClick"],
  269.                 [stringTable valueForStringKey:"clickedTwice"],
  270.             NULL, NULL);
  271.     return self;
  272. }
  273.  
  274. - displayInfoPanel:sender
  275. {
  276.     if (!infoPanel) {
  277.     [NXApp loadNibSection:"InfoPanel.nib" owner:self];
  278.     }
  279.     [infoPanel makeKeyAndOrderFront:NULL];
  280.     
  281.     return self;
  282. }
  283.  
  284. @end